home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr49 / 115_01.zip / ED3.C < prev    next >
Text File  |  1993-06-01  |  13KB  |  701 lines

  1. /*
  2.  * Screen editor:  command mode commands
  3.  *
  4.  * Source: ed3.c
  5.  * Version: September 5, 1981.
  6.  *
  7.  */
  8.  
  9. /* data global to these routines */
  10.  
  11. char filename[SYSFNMAX];
  12.  
  13.  
  14. /* append command.
  15.  * load a file into main buffer at current location.
  16.  * this command does NOT change the current file name.
  17.  */
  18.  
  19. append(args) char *args;
  20. {
  21. char buffer[MAXLEN];        /* disk line buffer */
  22. int file;
  23. int n;
  24. int topline;
  25. char locfn[SYSFNMAX];        /* local file name */
  26.     /* get file name which follows command */
  27.     if (name1(args,locfn)==ERR) {
  28.         return;
  29.     }
  30.     if (locfn[0]==EOS) {
  31.         message("no file argument");
  32.         return;
  33.     }
  34.     /* open the new file */
  35.     if ((file=sysopen(locfn,"r"))==ERR) {
  36.         message("file not found");
  37.         return;
  38.     }
  39.     /* read the file into the buffer */
  40.     while ((n=readline(file,buffer,MAXLEN))>=0) {
  41.         if (n>MAXLEN) {
  42.             message("line truncated");
  43.             n=MAXLEN;
  44.         }
  45.         if (bufins(buffer,n)==ERR) {
  46.             break;
  47.         }
  48.         if (bufdn()==ERR) {
  49.             break;
  50.         }
  51.     }
  52.     /* close the file */
  53.     sysclose(file);
  54.     /* redraw the screen so topline will be at top
  55.      * of the screen after command() does a CR/LF.
  56.      */
  57.     topline=max(1,bufln()-SCRNL2);
  58.     bufout(topline,2,SCRNL2);
  59.     bufgo(topline);
  60. }
  61.  
  62. /* global change command */
  63.  
  64. change(args) char *args;
  65. {
  66. char oldline[MAXLEN1];        /* reserve space for EOS */
  67. char newline[MAXLEN1];
  68. char oldpat[MAXLEN1];
  69. char newpat[MAXLEN1];
  70. int from, to, col, n, k;
  71.     if (get2args(args,&from,&to)==ERR) {
  72.         return;
  73.     }
  74.     /* get search and change masks into oldpat, newpat */
  75.     fmtsout("search mask ?  ",0);
  76.     getcmnd(oldpat,15);
  77.     fmtcrlf();
  78.     if (oldpat[0]==EOS) {
  79.         return;
  80.     }
  81.     pmtline();
  82.     fmtsout("change mask ?  ",0);
  83.     getcmnd(newpat,15);
  84.     fmtcrlf();
  85.     /* make substitution for lines between from, to */
  86.     while (from<=to) {
  87.         if (chkkey()==YES) {
  88.             break;
  89.         }
  90.         if (bufgo(from++)==ERR) {
  91.             break;
  92.         }
  93.         if (bufatbot()==YES) {
  94.             break;
  95.         }
  96.         n=bufgetln(oldline,MAXLEN);
  97.         n=min(n,MAXLEN);
  98.         oldline[n]=EOS;
  99.         /* '^' anchors search */
  100.         if (oldpat[0]=='^') {
  101.             if (amatch(oldline,oldpat+1,0)==YES) {
  102.                 k=replace(oldline,newline,
  103.                     oldpat+1,newpat,0);
  104.                 if (k==ERR) {
  105.                     return;
  106.                 }
  107.                 fmtcrlf();
  108.                 putdec(bufln(),5);
  109.                 fmtsout(newline,5);
  110.                 outdeol();
  111.                 bufrepl(newline,k);
  112.             }
  113.             continue;
  114.         }
  115.         /* search oldline for oldpat */
  116.         col=0;
  117.         while (col<n) {
  118.             if (amatch(oldline,oldpat,col++)==YES){
  119.                 k=replace(oldline,newline,
  120.                     oldpat,newpat,col-1);
  121.                 if (k==ERR) {
  122.                     return;
  123.                 }
  124.                 fmtcrlf();
  125.                 putdec(bufln(),5);
  126.                 fmtsout(newline,5);
  127.                 outdeol();
  128.                 bufrepl(newline,k);
  129.                 break;
  130.             }
  131.         }
  132.     }
  133.     fmtcrlf();
  134. }
  135.  
  136. /* clear main buffer and file name */
  137.  
  138. clear()
  139. {
  140.     /* make sure it is ok to clear buffer */
  141.     if (chkbuf()==YES) {
  142.         filename[0]=0;
  143.         pmtfile("");
  144.         outclr();
  145.         outxy(0,SCRNL1);
  146.         bufnew();
  147.         message("buffer cleared");
  148.     }
  149. }
  150.  
  151. /* multiple line delete command */
  152.  
  153. delete(args) char *args;
  154. {
  155. int from, to;
  156.     if (get2args(args,&from,&to)==ERR) {
  157.         return;
  158.     }
  159.     if (from>to) {
  160.         return;
  161.     }
  162.     /* go to first line to be deleted */
  163.     if (bufgo(from)==ERR) {
  164.         return;
  165.     }
  166.     /* delete all line between from and to */
  167.     if (bufdeln(to-from+1)==ERR) {
  168.         return;
  169.     }
  170.     /* redraw the screen */
  171.     bufout(bufln(),1,SCRNL1);
  172. }
  173.  
  174. /* search all lines below the current line for a pattern
  175.  * return -1 if pattern not found.
  176.  * otherwise, return column number of start of pattern.
  177.  */
  178.  
  179. find()
  180. {
  181.     return(search1(bufln()+1,HUGE,YES));
  182. }
  183.  
  184. /* list lines to list device */
  185.  
  186. list(args) char *args;
  187. {
  188. char linebuf[MAXLEN1];
  189. int n;
  190. int from, to, line, oldline;
  191.     /* save the buffer's current line */
  192.     oldline=bufln();
  193.     /* get starting, ending lines to print */
  194.     if (get2args(args,&from,&to)==ERR) {
  195.         return;
  196.     }
  197.     /* print lines one at a time to list device */
  198.     line=from;
  199.     while (line<=to) {
  200.         /* make sure prompt goes to console */
  201.         fmtassn(NO);
  202.         /* check for interrupt */
  203.         if (chkkey()==YES) {
  204.             break;
  205.         }
  206.         /* print line to list device */
  207.         fmtassn(YES);
  208.         if (bufgo(line++)!=OK) {
  209.             break;
  210.         }
  211.         if (bufatbot()) {
  212.             break;
  213.         }
  214.         n=bufgetln(linebuf,MAXLEN1);
  215.         n=min(n,MAXLEN);
  216.         linebuf[n]=CR;
  217.         fmtsout(linebuf,0);
  218.         fmtcrlf();
  219.     }
  220.     /* redirect output to console */
  221.     fmtassn(NO);
  222.     /* restore cursor */
  223.     bufgo(oldline);
  224. }
  225.  
  226. /* load file into buffer */
  227.  
  228. load (args) char *args;
  229. {
  230. char buffer[MAXLEN];    /* disk line buffer */
  231. char locfn [SYSFNMAX];  /* file name until we check it */
  232. int n;
  233. int file;
  234. int topline;
  235.     /* get filename following command */
  236.     if (name1(args,locfn)==ERR) {
  237.         return;
  238.     }
  239.     if (locfn[0]==EOS) {
  240.         message("no file argument");
  241.         return;
  242.     }
  243.     /* give user a chance to save the buffer */
  244.     if (chkbuf()==NO) {
  245.         return;
  246.     }
  247.     /* open the new file */
  248.     if ((file=sysopen(locfn,"r"))==ERR) {
  249.         message("file not found");
  250.         return;
  251.     }
  252.     /* update file name */
  253.     syscopfn(locfn, filename);
  254.     pmtfile(filename);
  255.     /* clear the buffer */
  256.     bufnew();
  257.     /* read the file into the buffer */
  258.     while ((n=readline(file,buffer,MAXLEN))>=0) {
  259.         if (n>MAXLEN) {
  260.             message("line truncated");
  261.             n=MAXLEN;
  262.         }
  263.         if (bufins(buffer,n)==ERR) {
  264.             break;
  265.         }
  266.         if (bufdn()==ERR) {
  267.             break;
  268.         }
  269.     }
  270.     /* close the file */
  271.     sysclose(file);
  272.     /* indicate that the buffer is fresh */
  273.     bufsaved();
  274.     /* set current line to line 1 */
  275.     bufgo(1);
  276.     /* redraw the screen so that topline will be
  277.      * on line 1 after command() does a CR/LF.
  278.      */
  279.     topline=max(1,bufln()-SCRNL2);
  280.     bufout(topline,2,SCRNL2);
  281.     bufgo(topline);
  282. }
  283.  
  284. /* change current file name */
  285.  
  286. name(args) char *args;
  287. {
  288.     name1(args,filename);
  289.     pmtfile(filename);
  290. }
  291.  
  292. /* check syntax of args.
  293.  * copy to filename.
  294.  * return OK if the name is valid.
  295.  */
  296.  
  297. name1(args,filename) char *args, *filename;
  298. {
  299.     /* skip command */
  300.     args=skiparg(args);
  301.     args=skipbl(args);
  302.     /* check file name syntax */
  303.     if (syschkfn(args)==ERR) {
  304.         return(ERR);
  305.     }
  306.     /* copy filename */
  307.     syscopfn(args,filename);
  308.     return(OK);
  309. }
  310.  
  311. /* save the buffer in an already existing file */
  312.  
  313. resave()
  314. {
  315. char linebuf[MAXLEN];
  316. int file, n, oldline;
  317.     /* make sure file has a name */
  318.     if (filename[0]==EOS) {
  319.         message("file not named");
  320.         return;
  321.     }
  322.     /* the file must exist for resave */
  323.     if ((file=sysopen(filename,"r"))==ERR) {
  324.         message("file not found");
  325.         return;
  326.     }
  327.     if (sysclose(file)==ERR) {
  328.         return;
  329.     }
  330.     /* open the file for writing */
  331.     if ((file=sysopen(filename,"w"))==ERR) {
  332.         return;
  333.     }
  334.     /* save the current position of file */
  335.     oldline=bufln();
  336.     /* write out the whole file */
  337.     if (bufgo(1)==ERR) {
  338.         sysclose(file);
  339.         return;
  340.     }
  341.     while (bufatbot()==NO) {
  342.         n=bufgetln(linebuf,MAXLEN);
  343.         n=min(n,MAXLEN);
  344.         if (pushline(file,linebuf,n)==ERR) {
  345.             break;
  346.         }
  347.         if (bufdn()==ERR) {
  348.             break;
  349.         }
  350.     }
  351.     /* indicate if all buffer was saved */
  352.     if (bufatbot()){
  353.         bufsaved();
  354.     }
  355.     /* close file and restore line number */
  356.     sysclose(file);
  357.     bufgo(oldline);
  358. }
  359.  
  360. /* save the buffer in a new file */
  361.  
  362. save()
  363. {
  364. char linebuf[MAXLEN];
  365. int file, n, oldline;
  366.     /* make sure the file is named */
  367.     if (filename[0]==EOS) {
  368.         message("file not named");
  369.         return;
  370.     }
  371.     /* file must NOT exist for save */
  372.     if ((file=sysopen(filename,"r"))!=ERR) {
  373.         sysclose(file);
  374.         message("file exists");
  375.         return;
  376.     }
  377.     /* open file for writing */
  378.     if ((file=sysopen(filename,"w"))==ERR) {
  379.         return;
  380.     }
  381.     /* remember current line */
  382.     oldline=bufln();
  383.     /* write entire buffer to file */
  384.     if (bufgo(1)==ERR) {
  385.         sysclose(file);
  386.         return;
  387.     }
  388.     while (bufatbot()==NO) {
  389.         n=bufgetln(linebuf,MAXLEN);
  390.         n=min(n,MAXLEN);
  391.         if (pushline(file,linebuf,n)==ERR) {
  392.             break;
  393.         }
  394.         if (bufdn()==ERR) {
  395.             break;
  396.         }
  397.     }
  398.     /* indicate buffer saved if good write */
  399.     if (bufatbot()) {
  400.         bufsaved();
  401.     }
  402.     /* restore line and close file */
  403.     bufgo(oldline);
  404.     sysclose(file);
  405. }
  406.  
  407. /* global search command */
  408.  
  409. search(args) char *args;
  410. {
  411. int from, to;
  412.  
  413.     if (get2args(args,&from,&to)==ERR) {
  414.         return;
  415.     }
  416.     search1(from, to, NO);
  417. }
  418.  
  419. /* search lines for a pattern.
  420.  * if flag == YES: stop at the first match.
  421.  *                 return -1 if no match.
  422.  *                 otherwise return column number of match.
  423.  * if flag == NO:  print all matches found.
  424.  */
  425.  
  426. search1(from, to, flag) int from, to, flag;
  427. {
  428. char pat  [MAXLEN1];        /* reserve space for EOS */
  429. char line [MAXLEN1];
  430. int col, n;
  431.     /* get search mask into pat */
  432.     fmtsout("search mask ?  ",0);
  433.     getcmnd(pat,15);
  434.     fmtcrlf();
  435.     if (pat[0]==EOS) {
  436.         return;
  437.     }
  438.     /* search all lines between from and to for pat */
  439.     while (from<=to) {
  440.         if (chkkey()==YES) {
  441.             break;
  442.         }
  443.         if (bufgo(from++)==ERR) {
  444.             break;
  445.         }
  446.         if (bufatbot()==YES) {
  447.             break;
  448.         }
  449.         n=bufgetln(line,MAXLEN);
  450.         n=min(n,MAXLEN);
  451.         line[n]=EOS;
  452.         /* ^ anchors search */
  453.         if (pat[0]=='^') {
  454.             if (amatch(line,pat+1,0)==YES) {
  455.                 if (flag==NO) {
  456.                     fmtcrlf();
  457.                     putdec(bufln(),5);
  458.                     fmtsout(line,5);
  459.                     outdeol();
  460.                 }
  461.                 else {
  462.                     return(0);
  463.                 }
  464.             }
  465.             continue;
  466.         }
  467.         /* search whole line for match */
  468.         col=0;
  469.         while (col<n) {
  470.             if (amatch(line,pat,col++)==YES) {
  471.                 if (flag==NO) {
  472.                     fmtcrlf();
  473.                     putdec(bufln(),5);
  474.                     fmtsout(line,5);
  475.                     outdeol();
  476.                     break;
  477.                 }
  478.                 else {
  479.                     return(col-1);
  480.                 }
  481.             }
  482.         }
  483.     }
  484.     /* all searching is finished */
  485.     if (flag==YES) {
  486.         return(-1);
  487.     }
  488.     else {
  489.         fmtcrlf();
  490.     }
  491. }
  492.  
  493. /* set tab stops for fmt routines */
  494.  
  495. tabs(args) char *args;
  496. {
  497. int n, junk;
  498.     if (get2args(args,&n,&junk)==ERR) {
  499.         return;
  500.     }
  501.     fmtset(n);
  502. }
  503.  
  504. /* return YES if buffer may be drastically changed */
  505.  
  506. chkbuf()
  507. {
  508.     if (bufchng()==NO) {
  509.         /* buffer not changed. no problem */
  510.         return(YES);
  511.     }
  512.     fmtsout("buffer not saved. proceed ?  ",0);
  513.     pmtline();
  514.     if (tolower(syscout(syscin()))!='y') {
  515.         fmtcrlf();
  516.         message("cancelled");
  517.         return(NO);
  518.     }
  519.     else {
  520.         fmtcrlf();
  521.         return(YES);
  522.     }
  523. }
  524.  
  525. /* print message from a command */
  526.  
  527. message(s) char *s;
  528. {
  529.     fmtsout(s,0);
  530.     fmtcrlf();
  531. }
  532.  
  533. /* get two arguments the argument line args.
  534.  * no arguments imply 1 HUGE.
  535.  * one argument implies both args the same.
  536.  */
  537.  
  538. get2args(args,val1,val2) char *args; int *val1, *val2;
  539. {
  540.     /* skip over the command */
  541.     args=skiparg(args);
  542.     args=skipbl(args);
  543.     if (*args==EOS) {
  544.         *val1=1;
  545.         *val2=HUGE;
  546.         return(OK);
  547.     }
  548.     /* check first argument */
  549.     if (number(args,val1)==NO) {
  550.         message("bad argument");
  551.         return(ERR);
  552.     }
  553.     /* skip over first argument */
  554.     args=skiparg(args);
  555.     args=skipbl(args);
  556.     /* 1 arg: arg 2 is HUGE */
  557.     if (*args==EOS) {
  558.         *val2=HUGE;
  559.         return(OK);
  560.     }
  561.     /* check second argument */
  562.     if (number(args,val2)==NO) {
  563.         message("bad argument");
  564.         return(ERR);
  565.     }
  566.     else {
  567.         return(OK);
  568.     }
  569. }
  570.  
  571. /* skip over all except EOS, and blanks */
  572.  
  573. skiparg(args) char *args;
  574. {
  575.     while ((*args!=EOS)&(*args!=' ')) {
  576.         args++;
  577.     }
  578.     return(args);
  579. }
  580.  
  581. /* skip over all blanks */
  582.  
  583. skipbl(args) char *args;
  584. {
  585.     while (*args==' ') {
  586.         args++;
  587.     }
  588.     return(args);
  589. }
  590.  
  591. /* return YES if the user has pressed any key.
  592.  * blanks cause a transparent pause.
  593.  */
  594. chkkey()
  595. {
  596. int c;
  597.     c=syscstat();
  598.     if (c==0) {
  599.         /* no character at keyboard */
  600.         return(NO);
  601.     }
  602.     else if (c==' ') {
  603.         /* pause.  another blank ends pause */
  604.         pmtline();
  605.         if (syscin()==' ') {
  606.             return(NO);
  607.         }
  608.     }
  609.     /* we got a nonblank character */
  610.     return(YES);
  611. }
  612.  
  613. /* anchored search for pattern in text line at column col.
  614.  * return YES if the pattern starts at col.
  615.  */
  616.  
  617. amatch(line,pat,col) char *line, *pat; int col;
  618. {
  619. int k;
  620.     k=0;
  621.     while (pat[k]!=EOS) {
  622.         if (pat[k]==line[col]) {
  623.             k++;
  624.             col++;
  625.         }
  626.         else if ((pat[k]=='?')&(line[col]!=EOS)) {
  627.             /* question mark matches any char */
  628.             k++;
  629.             col++;
  630.         }
  631.         else {
  632.             return(NO);
  633.         }
  634.     }
  635.     /* the entire pattern matches */
  636.     return(YES);
  637. }
  638.  
  639. /* replace oldpat in oldline by newpat starting at col.
  640.  * put result in newline.
  641.  * return number of characters in newline.
  642.  */
  643.  
  644. replace(oldline,newline,oldpat,newpat,col)
  645. char *oldline, *newline, *oldpat, *newpat; int col;
  646. {
  647. int k;
  648. char *tail, *pat;
  649.     /* copy oldline preceding col to newline */
  650.     k=0;
  651.     while (k<col) {
  652.         newline[k++]=*oldline++;
  653.     }
  654.     /* remember where end of oldpat in oldline is */
  655.     tail=oldline;
  656.     pat=oldpat;
  657.     while (*pat++!=EOS) {
  658.         tail++;
  659.     }
  660.     /* copy newpat to newline.
  661.      * use oldline and oldpat to resolve question marks
  662.      * in newpat.
  663.      */
  664.     while (*newpat!=EOS) {
  665.         if (k>MAXLEN-1) {
  666.             message("new line too long");
  667.             return(ERR);
  668.         }
  669.         if (*newpat!='?') {
  670.             /* copy newpat to newline */
  671.             newline[k++]=*newpat++;
  672.             continue;
  673.         }
  674.         /* scan for '?' in oldpat */
  675.         while (*oldpat!='?') {
  676.             if (*oldpat==EOS) {
  677.                 message(
  678.                 "too many ?'s in change mask"
  679.                 );
  680.                 return(ERR);
  681.             }
  682.             oldpat++;
  683.             oldline++;
  684.         }
  685.         /* copy char from oldline to newline */
  686.         newline[k++]=*oldline++;
  687.         oldpat++;
  688.         newpat++;
  689.     }
  690.     /* copy oldline after oldpat to newline */
  691.     while (*tail!=EOS) {
  692.         if (k>=MAXLEN-1) {
  693.             message("new line too long");
  694.             return(ERR);
  695.         }
  696.         newline[k++]=*tail++;
  697.     }
  698.     newline[k]=EOS;
  699.     return(k);
  700. }
  701.